#define _CRT_SECURE_NO_DEPRECATE
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include "ext_rational.h"

#pragma comment(linker, "/STACK:200000000")

using namespace std;

#define OUTPUT_PROGRESS false
#define OUTPUT_ADDITIONAL_DATA false
#define OUTPUT_ANTIDICTIONARY false
#define OUTPUT_DFA false
#define USE_ORACLE false
#define ADD_LOOPS false

#ifdef __GNUC__
  typedef long long i64;
#else
  typedef __int64 i64;
#endif

int ALPH_SIZE;
int ROOT_LENGTH;
ext_rational beta;
double delta;

// ANTIDICTIONARY CONSTRUCTION

const int QUEUE_SIZE = 1<<28;
const int DFA_SIZE = 1<<22;
const int MAX_WORD_LENGTH = 10000;

int max_words_queue_size;
char *words_queue;
int qbeg, qend;
char *bij;

int total, words_num;
//int ** dfa;
int * dfa;

void init(){
  words_queue = new char [QUEUE_SIZE];
  max_words_queue_size = 0;
  bij = new char [ALPH_SIZE+1];
  //dfa = new int* [DFA_SIZE];
  dfa = new int [DFA_SIZE * ALPH_SIZE];
  total = 1;
  /*for (int i=0; i<=total; i++){
    dfa[i] = new int [ALPH_SIZE];
    memset(dfa[i], 0, sizeof(int) * ALPH_SIZE);
  }*/
  memset(dfa, 0, sizeof(int) * DFA_SIZE * ALPH_SIZE);
  qbeg = 0;
  qend = 0;
}

inline void push_symbol(char ch){
  words_queue[qend] = ch;
  qend = (qend + 1) & (QUEUE_SIZE-1);
  if (qbeg == qend){
    printf("ERROR! Insufficient words queue size!\n");
    exit(1);
  }
  if (OUTPUT_ADDITIONAL_DATA){
    int zsize = (qend - qbeg + QUEUE_SIZE) & (QUEUE_SIZE - 1);
    if (zsize > max_words_queue_size){
      max_words_queue_size = zsize;
    }
  }
}

inline void push_word(char * word){
  int i;
  for (i=0; word[i]; i++){
    push_symbol(word[i]);
  }
}

bool forbidden(char * buff, int len, char dir){
  int cv = 1, i, sp = 0, fp = len, cur = 0;
  if (dir < 0){
    sp = len-1;
    fp = -1;
  }
  memset(bij, 0, sizeof(char)*ALPH_SIZE);
  for (i=sp; i!=fp; i+=dir){
    if (!bij[buff[i]-'a']){
      bij[buff[i]-'a'] = 'a' + cur;
      cur++;
    }
    int c = bij[buff[i]-'a'] - 'a';
    // int zv = dfa[cv][c];
    int zv = dfa[cv * ALPH_SIZE + c];
    if (!zv) return false;
    if (zv < 0) return true;
    cv = zv;
  }
  return false;
}

void add_word(char * word){
  int cv = 1, i;
  words_num++;
  for (i=0; word[i+1]; i++){
    int c = word[i]-'a';
    //if (!dfa[cv][c]){
    if (!dfa[cv*ALPH_SIZE + c]){
      total++;
      if (total >= DFA_SIZE){
        printf("ERROR! Insufficient DFA size!\n");
        exit(1);
      }
      /*dfa[total] = new int [ALPH_SIZE];
      memset(dfa[total], 0, sizeof(int) * ALPH_SIZE);
      dfa[cv][c] = total;*/
      dfa[cv*ALPH_SIZE + c] = total;
    }
    //cv = dfa[cv][c];
    cv = dfa[cv*ALPH_SIZE + c];
  }
  //dfa[cv][word[i]-'a'] = -1;
  dfa[cv*ALPH_SIZE + word[i]-'a'] = -1;
}

char thword[MAX_WORD_LENGTH + 1];

void handle_word(char* cword, int clen){
  char maxlet = 'a';
  int i;
  for (i=0; i<clen; i++){
    thword[i] = cword[i];
    if (thword[i] > maxlet){
      maxlet = thword[i];
    }
  }
  int blen = clen, cpos = 0;
  while (ext_rational(blen, clen, 0) < beta){
    thword[blen++] = thword[cpos];
    cpos = (cpos + 1) % clen;
  }

  thword[blen] = 0;

  if (blen > MAX_WORD_LENGTH){
    printf("Too little maximal length of forbidden word!\n");
    exit(1);
  }
  for (i=clen+1; i<blen; i++){
    if (forbidden(thword, i, -1)){
      return;
    }
  }
  if (forbidden(thword+1, blen-1, -1) || forbidden(thword, blen, 1)){
    return;
  }
  add_word(thword);
}

void build_antidictionary(){
  push_symbol(-1);
  push_symbol('a');
  int i;
  int clen = 0;
  char bad_word[MAX_WORD_LENGTH + 1];
  char dont_put_a;
  while (qbeg != qend){
    if (words_queue[qbeg] == -1){
      if (clen < ROOT_LENGTH){
        clen++;
        push_symbol(-1);
        qbeg = (qbeg + 1) & (QUEUE_SIZE - 1);
        continue;
      }
      else break;
    }
    // there is a word in the queue starting at qbeg with (length = clen)
    
    char maxlet = 'a';
    for (i=0; i<clen; i++){
      bad_word[i] = words_queue[(qbeg + i) & (QUEUE_SIZE - 1)];
      if (bad_word[i] > maxlet){
        maxlet = bad_word[i];
      }
    }
      
    int blen = clen, cpos = 0;
    while (ext_rational(blen, clen, 0) < beta){
      bad_word[blen++] = bad_word[cpos];
      cpos = (cpos + 1) % clen;
    }

    bad_word[blen] = 0;

    if (blen > MAX_WORD_LENGTH){
      printf("Too little maximal length of forbidden word!\n");
      exit(1);
    }

    int ok = 1;
    for (i=clen+1; i<blen; i++){
      if (forbidden(bad_word, i, -1)){
        ok = 0;
        break;
      }
    }
    dont_put_a = (i==clen+1);

    if (forbidden(bad_word+1, blen-1, -1) || forbidden(bad_word, blen, 1)){
      ok = 0;
    }

    if (ok){
      add_word(bad_word);
    }


    qbeg = (qbeg + clen) & (QUEUE_SIZE - 1);
    if (clen < ROOT_LENGTH){
      char ch;
      for (ch='a'+dont_put_a; ch<=maxlet; ch++){
        bad_word[clen] = ch;
        bad_word[clen+1] = 0;
        if (!forbidden(bad_word, clen+1, -1)){
          if (clen < ROOT_LENGTH - 1) push_word(bad_word);
          else handle_word(bad_word, clen+1);
        }
      }
      if (maxlet-'a'+1 < ALPH_SIZE){
        bad_word[clen] = maxlet+1;
        bad_word[clen+1] = 0;
        if (clen < ROOT_LENGTH - 1) push_word(bad_word);
        else handle_word(bad_word, clen+1);
      }
    }

  }

  delete[] words_queue;
  delete[] bij;

}

// AUTOMATON CONSTRUCTION

//#define MASK 15LL
const char MASK = 15;

char * last;
//i64 * sigma; // hardcore byte encoding here
//char ** sigma;
char * sigma;
int * back;
int * lf;

int * vert_queue;
int vqbeg, vqend, vqsize;

inline void push_vertex(int x){
  vert_queue[vqend] = x;
  vqend = (vqend + 1) & (vqsize - 1);
}

void make_permut(char* p1, char* p2){
  int i;
  for (i=0; i<ALPH_SIZE; i++){
    if (p1[i] >= 0){
      p1[i] = p2[p1[i]];
    }
  }
}

/*inline int take_val(i64 a, int i){
  return (int)((a & (MASK << 4*i)) >> 4*i);
}

inline void set_val(i64& a, int i, i64 v){
  a &= ~(MASK << 4*i);
  a |= (v << 4*i);
}

void make_permut(i64 & p1, i64 & p2){
  int i;
  for (i=0; i<ALPH_SIZE; i++){
    int val = take_val(p1, i);
    if (val != MASK){
      i64 val2 = take_val(p2, val);
      set_val(p1, i, val2);
    }
  }
}*/

/*inline char take_val(char* a, int i){
  return (char)((a[i>>1] & (MASK << 4*(i&1))) >> 4*(i&1));
}

inline void set_val(char* a, int i, char v){
  a[i>>1] -= (take_val(a, i) << 4*(i&1));
  a[i>>1] |= (v << 4*(i&1));
}

void make_permut (char * p1, char * p2){
  int i;
  for (i=0; i<ALPH_SIZE; i++){
    char val = take_val(p1, i);
    if (val != MASK){
      char val2 = take_val(p2, val);
      set_val(p1, i, val2);
    }
  }
}*/

void cnt_vertex(int v){
  int c;
  char * zsigma = new char [ALPH_SIZE];
  //char * zsigma = new char [(ALPH_SIZE+1)/2];
  //i64 zsigma;
  char clast = last[v];
  for (c=0; c<=clast+1; c++){
    if (c >= ALPH_SIZE) break;
    //if (!dfa[v][c]){
    if (!dfa[v*ALPH_SIZE + c]){
      //char d = sigma[v][c];
      //i64 d = take_val(sigma[v], c);
      //char d = take_val(sigma[v], c);
      char d = sigma[v*ALPH_SIZE + c];
      if (d < 0){
      //if (d == MASK){
        d = last[lf[v]] + 1;
      }
      //dfa[v][c] = dfa[lf[v]][d];
      dfa[v*ALPH_SIZE + c] = dfa[lf[v]*ALPH_SIZE + d];
      back[v] |= (1 << c);
    }
    else{
      //int u = dfa[v][c];
      int u = dfa[v*ALPH_SIZE + c];
      if (u < 0){
        //dfa[v][c] = 0;
        dfa[v*ALPH_SIZE + c] = 0;
        continue;
      }
      push_vertex(u);
      last[u] = (c > clast) ? c : clast;
      //memcpy(sigma[u], sigma[v], sizeof(char) * (ALPH_SIZE));
      //memcpy(sigma[u], sigma[v], sizeof(char) * ((ALPH_SIZE+1)/2));
      //sigma[u] = sigma[v];
      memcpy(sigma + u*ALPH_SIZE, sigma + v*ALPH_SIZE, sizeof(char)*ALPH_SIZE);
      //char d = sigma[v][c];
      //i64 d = take_val(sigma[v], c);
      //char d = take_val(sigma[v], c);
      char d = sigma[v*ALPH_SIZE + c];
      if (d < 0){
      //if (d == MASK){
        d = last[lf[v]] + 1;
        //sigma[u][c] = d;
        //set_val(sigma[u], c, d);
        sigma[u*ALPH_SIZE + c] = d;
      }
      //lf[u] = dfa[lf[v]][d];
      lf[u] = dfa[lf[v]*ALPH_SIZE + d];
      int zv = lf[v];
      /*while (back[zv] & (1 << sigma[u][c])){
        memcpy(zsigma, sigma[zv], sizeof(char) * ALPH_SIZE);
        if (zsigma[sigma[u][c]] < 0){
          zsigma[sigma[u][c]] = last[lf[zv]] + 1;
        }
        make_permut(sigma[u], zsigma);
        zv = lf[zv];
      }*/
      /*while (back[zv] & (1 << take_val(sigma[u], c))){
        zsigma = sigma[zv];
        if (take_val(zsigma, take_val(sigma[u], c)) == MASK){
          set_val(zsigma, take_val(sigma[u], c), last[lf[zv]] + 1);
        }
        make_permut(sigma[u], zsigma);
        zv = lf[zv];
      }*/
      while (back[zv] & (1 << sigma[u*ALPH_SIZE + c])){
        memcpy(zsigma, sigma + zv*ALPH_SIZE, sizeof(char) * ALPH_SIZE);
        if (zsigma[sigma[u*ALPH_SIZE + c]] < 0){
          zsigma[sigma[u*ALPH_SIZE + c]] = last[lf[zv]] + 1;
        }
        make_permut(sigma + u*ALPH_SIZE, zsigma);
        zv = lf[zv];
      }
    }
  }
  for (c=clast+2; c<ALPH_SIZE; c++){
    //dfa[v][c] = dfa[v][clast+1];
    dfa[v*ALPH_SIZE + c] = dfa[v*ALPH_SIZE + clast+1];
    if (back[v] & (1<<(clast+1))){
      back[v] |= (1<<c);
    }
  }
  delete[] zsigma;
}

void build_dfa(){
  //sigma = new char * [total + 1];
  //sigma = new i64 [total + 1];
  //sigma = new char * [total + 1];
  sigma = new char [(total + 1) * ALPH_SIZE];
  back = new int [total + 1];
  last = new char [total + 1];
  lf = new int [total + 1];
  int i;
  for (i=1; i<=total; i++){
    back[i] = 0;
    last[i] = 0;
    /*sigma[i] = new char [ALPH_SIZE];
    for (int j=0; j<ALPH_SIZE; j++){
      sigma[i][j] = -1;
    }*/
    //sigma[i] = 0xFFFFFFFFFFFFFFFF;
    /*sigma[i] = new char [(ALPH_SIZE+1)/2];
    memset(sigma[i], 0xFF, sizeof(char) * ((ALPH_SIZE+1)/2));*/
  }
  memset(sigma, 0xFF, sizeof(char) * (total + 1) * ALPH_SIZE);
  for (i=1; i<ALPH_SIZE; i++){
    //dfa[1][i] = 2;
    dfa[1*ALPH_SIZE + i] = 2;
  }
  
  vqsize = 1;
  while (vqsize < words_num) vqsize <<= 1;
  vert_queue = new int [vqsize];
  vqbeg = 0; vqend = 0;
  
  push_vertex(2);
  last[1] = -1;
  lf[1] = lf[2] = 1;

  while (vqbeg != vqend){
    cnt_vertex(vert_queue[vqbeg]);
    vqbeg = (vqbeg + 1) & (vqsize - 1);
  }

  /*for (i=1; i<=total; i++){
    delete[] sigma[i];
  }*/
  delete[] sigma;
  delete[] back;
  delete[] vert_queue;
  delete[] last;
  delete[] lf;
}

// ANSWER CALCULATION

double * cnt_new;
double * cnt_old;

double grate, mrate;

int scc_num, nontriv_scc_num, scc_size, scc_edgnum;
int * scc;

const int MAXITER = 1000;
const int MINITER = 25;

void cnt_algo2(){
  int i, j, k;
  char h;
  cnt_old = new double [total+1];
  memset(cnt_old, 0, sizeof(double) * (total + 1));
  if (OUTPUT_PROGRESS){
    printf("old\n");
    fflush(stdout);
  }
  cnt_new = new double [total+1];
  memset(cnt_new, 0, sizeof(double) * (total + 1));
  if (OUTPUT_PROGRESS){
    printf("new\n");
    fflush(stdout);
  }
  cnt_old[1] = 1;
  double pcomp = 1, ccomp, last_loc_max = 0, last_loc_min = 0;
  double rates[MAXITER];
  for (i=0; i<MAXITER; i++){
    for (j=1; j<=total; j++){
      for (h=0; h<ALPH_SIZE; h++){
        //k = dfa[j][h];
        k = dfa[j*ALPH_SIZE + h];
        if (!k) continue;
        cnt_new[k] += cnt_old[j];
      }
      if (ADD_LOOPS) cnt_new[j] += cnt_old[j];
    }
    ccomp = 0;
    for (j=1; j<=total; j++){
      ccomp += cnt_new[j];
      cnt_old[j] = cnt_new[j];
      cnt_new[j] = 0;
    }
    rates[i] = ccomp / pcomp;
    // ORACLE HERE
    if (i >= MINITER){
      if ((rates[i-1] >= rates[i-2]) && (rates[i-1] >= rates[i])) last_loc_max = rates[i-1];
      if ((rates[i-1] <= rates[i-2]) && (rates[i-1] <= rates[i])) last_loc_min = rates[i-1];
      if (fabs(rates[i] - rates[i-1]) < delta){
        // Oscillating
        if ((last_loc_max > 0) && (last_loc_min > 0)){
          if (last_loc_max - last_loc_min < delta){
            if (OUTPUT_PROGRESS){
              printf("Oscillating sequence! The number of iterations = %d\n", i);
            }
            grate = rates[i] - (ADD_LOOPS == true);
            return;
          }
        }
        // Monotonic
        else{
          if (OUTPUT_PROGRESS){
            printf("Monotonic sequence! The number of iterations = %d\n", i);
          }
          double q = pow(fabs(rates[i]-rates[i-1]), 1.0 / i);
          double sum = (rates[i] - rates[i-1]) / (1 - q);
          grate = rates[i-1] + sum - (ADD_LOOPS == true);
          return;
        }
      }
    }
    pcomp = ccomp;
  }
  if (OUTPUT_PROGRESS){
    printf("\nNot enough iterations! Current difference is %.20lf\n\n", rates[i-1] - rates[i-2]);
  }
  grate = rates[i-1] - (ADD_LOOPS == true);
}

int * edge1;
int * edge2;

void cnt_algo1(){
  double minrate, maxrate, crate, alpha;
  int i, iter = 0;
  //int j;
  while (iter < MAXITER){
    iter++;
    /*for (i=1; i<=scc_size; i++){
      for (j=0; j<ALPH_SIZE; j++){
        if (dfa[i][j] > 0){
          cnt_new[dfa[i][j]] += cnt_old[i];
        }
      }
      if (ADD_LOOPS) cnt_new[i] += cnt_old[i];
    }*/
    for (i=0; i<scc_edgnum; i++){
      cnt_new[edge2[i]] += cnt_old[edge1[i]];
    }
    minrate = 1e100;
    maxrate = 0;
    for (i=1; i<=scc_size; i++){
      if (ADD_LOOPS) cnt_new[i] += cnt_old[i];
      crate = cnt_new[i] / cnt_old[i];
      if (crate < minrate) minrate = crate;
      if (crate > maxrate) maxrate = crate;
      cnt_old[i] = cnt_new[i];
      cnt_new[i] = 0;
    }
    //printf("\nITERATION %d: %.20lf\n", ++iter, (maxrate+minrate)/2);
    if (maxrate - minrate < 2 * delta){
      alpha = (minrate + maxrate) / 2 - (ADD_LOOPS == true);
      if (alpha > grate) grate = alpha;
      if (OUTPUT_PROGRESS) printf("\n%d iterations used\n\n", iter);
      return;
    }
  }
  if (OUTPUT_PROGRESS) printf("\nNot enough iterations or precision error! %.20lf precision only!\n\n", (maxrate-minrate)/2);
  grate = (minrate + maxrate) / 2 - (ADD_LOOPS == true);
}

// Works for one scc only!
void solve_scc(int id){
  int i, j = 1;
  
  for (i=1; i<=total; i++){
    if (scc[i] == id){
      scc[i] = -j;
      j++;
    }
  }
  
  for (i=1; i<=total; i++){
    if (scc[i] >= 0) continue;
    for (j=0; j<ALPH_SIZE; j++){
      /*if (scc[dfa[i][j]] >= 0){
        dfa[-scc[i]][j] = 0;
      }*/
      if (scc[dfa[i*ALPH_SIZE + j]] >= 0){
        dfa[-scc[i]*ALPH_SIZE + j] = 0;
      }
      else{
        //dfa[-scc[i]][j] = -scc[dfa[i][j]];
        dfa[-scc[i]*ALPH_SIZE + j] = -scc[dfa[i*ALPH_SIZE + j]];
        scc_edgnum++;
      }
    }
  }
  
  delete[] scc;
  
  edge1 = new int [scc_edgnum];
  edge2 = new int [scc_edgnum];
  int cnum = 0;
  for (i=1; i<=scc_size; i++){
    for (j=0; j<ALPH_SIZE; j++){
      //if (dfa[i][j] > 0){
      if (dfa[i*ALPH_SIZE + j] > 0){
        edge1[cnum] = i;
        //edge2[cnum++] = dfa[i][j];
        edge2[cnum++] = dfa[i*ALPH_SIZE + j];
      }
    }
  }

  /*for (i=0; i<=total; i++){
    delete[] dfa[i];
  }*/
  delete[] dfa;

  cnt_old = new double [scc_size + 1];
  cnt_new = new double [scc_size + 1];
  for (i=1; i<=scc_size; i++){
    cnt_new[i] = 0;
    cnt_old[i] = 1;
  }
  
  if (scc_edgnum == scc_size){
    if (grate == 0) grate = 1;
    return;
  }
  nontriv_scc_num++;
  cnt_algo1();
  delete[] edge1;
  delete[] edge2;
}

// TARJAN ALGORITHM

int * stack;
int * in_time;
int * z_time;
char * instack;
int ssize, curtime;

void dfs(int v){
  int k;
  char i;
  ++curtime;
  in_time[v] = z_time[v] = curtime;
  stack[++ssize] = v;
  instack[v] = 1;
  for (i=0; i<ALPH_SIZE; i++){
    //k = dfa[v][i];
    k = dfa[v*ALPH_SIZE + i];
    if (!k) continue;
    if (!in_time[k]){
      dfs(k);
      if (z_time[k] < z_time[v]){
        z_time[v] = z_time[k];
      }
    }
    else if (instack[k] && z_time[k] < z_time[v]){
      z_time[v] = z_time[k];
    }
  }
  if (scc_num > 1) return;
  if (z_time[v] == in_time[v]){
    if (stack[ssize] == v){
      scc[v] = 0;
      instack[v] = 0;
      ssize--;
    }
    else{
      scc_num++;
      if (scc_num > 1){
        if (OUTPUT_PROGRESS) printf("Achtung! There is more than one scc!\n");
        fflush(stdout);
        return;
      }
      do{
        k = stack[ssize--];
        scc[k] = scc_num;
        scc_size++;
        instack[k] = 0;
      }while (k != v);
    }
  }
}

void divide_scc_solve(){
  if (!USE_ORACLE){
    stack = new int [total + 1];
    ssize = 0;
    in_time = new int [total + 1];
    memset(in_time, 0, sizeof(int) * (total + 1));
    curtime = 0;
    z_time = new int [total + 1];
    instack = new char [total + 1];
    memset(instack, 0, sizeof(char) * (total + 1));
    scc = new int [total + 1];
    memset(scc, 0, sizeof(int) * (total + 1));
    dfs(1);
    delete[] stack;
    delete[] in_time;
    delete[] instack;
    delete[] z_time;
    if (OUTPUT_PROGRESS){
      printf("The number of non-singleton strongly connected components: %d\n", scc_num);
      fflush(stdout);
    }
    if (scc_num < 2){
      solve_scc(1);
    }
    if (OUTPUT_PROGRESS){
      printf("The number of non-trivial scc: %d\n", nontriv_scc_num);
      printf("The number of vertices in scc: %d\n", scc_size);
      printf("The number of edges in scc: %d\n", scc_edgnum);
      printf("\n");
      fflush(stdout);
    }
  }
  else{
    cnt_algo2();
  }
}

// DEBUG OUTPUT



void dfs_output(int cv, const string& str){
  if (cv < 0) printf("%s\n", str.c_str());
  int i;
  for (i=0; i<ALPH_SIZE; i++){
    //if (dfa[cv][i]){
    if (dfa[cv*ALPH_SIZE + i]){
      string ns = str;
      ns += 'a'+i;
      //dfs_output(dfa[cv][i], ns);
      dfs_output(dfa[cv*ALPH_SIZE + i], ns);
    }
  }
}


void output_dfa(){
  int i, j;
  printf("\n");
  for (i=1; i<=total; i++){
    printf("Vertex number %d: \n", i);
    for (j=0; j<ALPH_SIZE; j++){
      //printf("%d ", dfa[i][j]);
      printf("%d ", dfa[i*ALPH_SIZE + j]);
    }
    printf("\n\n");
  }
}

void clear_data(){
  grate = 0;
  mrate = 0;
  scc_num = 0;
  nontriv_scc_num = 0;
  scc_size = 0;
  scc_edgnum = 0;
  words_num = 0;
  if (USE_ORACLE){
    /*int i;
    for (i=0; i<=total; i++){
      delete[] dfa[i];
    }*/
    delete[] dfa;
  }
  delete[] cnt_new;
  delete[] cnt_old;
}

int main(){
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  while (scanf("%d%d", &ALPH_SIZE, &ROOT_LENGTH) > 0){
    if (ALPH_SIZE < 0) break;
    scanf("%d%d%d", &beta.num, &beta.denum, &beta.p);
    scanf("%lf", &delta);
    if (OUTPUT_PROGRESS){
      printf("Calculating answer for test:\nAlphabet size = %d, Root length <= %d\nExponent = %d/%d", ALPH_SIZE, ROOT_LENGTH, beta.num, beta.denum);
      if (beta.p) printf("+");
      printf("\nPrecision = %.20lf\n\n", delta);
    }
    init();
  
    build_antidictionary();

    if (OUTPUT_ANTIDICTIONARY){
      dfs_output(1, "");
      fflush(stdout);
    }
  
    int vert_num = total;
    if (OUTPUT_ADDITIONAL_DATA){
      printf("Maximal queue size = %d\n", max_words_queue_size);
    }
    if (OUTPUT_PROGRESS){
      printf("The number of words = %d\n", words_num);
      printf("The number of vertices = %d\n", vert_num);
      fflush(stdout);
    }
  
    build_dfa();
    if (OUTPUT_DFA){
      output_dfa();
      fflush(stdout);
    }
    if (OUTPUT_PROGRESS){
      printf("\nDFA built!\n\n");
      fflush(stdout);
    }

    divide_scc_solve();
  
    printf("%.13lf\n", grate);
    fflush(stdout);
    clear_data();
  }
  return 0;
}
